import { _decorator, animation, Component, error, instantiate, log, Node, Prefab, tween, v2, v3, Vec2, Vec3 } from 'cc';
import { CardData, CardStruct, E_CardStar } from './CardData';
import { CardItem } from './CardItem';
const { ccclass, property } = _decorator;

@ccclass('Main')
export class Main extends Component {

    @property({ type: Node, displayName: '卡牌父节点' })
    node_cardRoot: Node = null;
    @property({ type: Prefab, displayName: '卡牌预制' })
    pre_card: Prefab = null;
    /** 卡牌item */
    comp_cardItem: CardItem[] = [];
    readonly cardPos: Vec3[] = [v3(480), v3(320), v3(160), v3(0), v3(-160), v3(-320), v3(-480)];

    isPlayingAnima: boolean = false;

    start() {
        this.initCard();
    }

    initCard() {
        for (let i = 0; i < CardData.ins.CardArrLength; i++) {
            let node = instantiate(this.pre_card);
            let comp = node.getComponent(CardItem);
            comp.setData(CardData.ins.getCard());
            node.setParent(this.node_cardRoot);
            node.setPosition(this.cardPos[i]);
            this.comp_cardItem.push(node.getComponent(CardItem));
        }
        this.judgeAdjacent();
    }

    /** 判断相邻 */
    judgeAdjacent() {
        for (let i = this.comp_cardItem.length - 1; i > 0; i--) {
            let rightIndex = i - 1;
            let isSame = this.getIDAndStarSame(this.comp_cardItem[i].data, this.comp_cardItem[rightIndex].data);
            // 找到相同 播放动画
            if (isSame) {
                this.sameCardAdmin(i, rightIndex);
                return;
            }
        }
        this.isPlayingAnima = false;
    }

    /** 相邻且相同 播放动画 */
    sameCardAdmin(leftIdx: number, rightIdx: number) {
        log('相邻且相同 播放动画', leftIdx, rightIdx)
        let currentX = this.comp_cardItem[leftIdx].node.getPosition().x;
        let targetX = this.comp_cardItem[rightIdx].node.getPosition().x;
        let moveX = (targetX - currentX) / 2;

        const time = 0.5;
        let promise1 = new Promise<void>((resolve, reject) => {
            tween(this.comp_cardItem[leftIdx].node)
                .by(time, { position: v3(moveX, 0, 0) })
                .call(() => resolve())
                .start();
        })
        let promise2 = new Promise<void>((resolve, reject) => {
            tween(this.comp_cardItem[rightIdx].node)
                .by(time, { position: v3(-moveX, 0, 0) })
                .call(() => resolve())
                .start();
        })

        let endX = currentX + moveX;
        Promise.all([promise1, promise2]).then(() => {
            log('合成成功');
            this.compoundDispose(leftIdx, rightIdx, endX);
        })
    }

    /** 合成后处理 */
    compoundDispose(leftIdx: number, rightIdx: number, endX: number) {
        // 先销毁节点
        let comp1 = this.comp_cardItem.splice(leftIdx, 1);
        comp1[0].node.destroy();
        let comp2 = this.comp_cardItem.splice(rightIdx, 1);
        comp2[0].node.destroy();
        this.ConsoleItemData('11111');
        let t_idx = rightIdx == 0 ? 0 : rightIdx;
        log('t_idx', t_idx)
        // 再生成新节点
        this.comp_cardItem.splice(t_idx, 0, this.generateNode(t_idx, comp1[0], endX));
        this.ConsoleItemData('22222');
    }

    /** 生成新的节点 */
    generateNode(idx: number, cardItem: CardItem, endX: number): CardItem {
        const time = 0.5;
        let node = instantiate(this.pre_card);
        let comp = node.getComponent(CardItem);
        comp.setData(new CardStruct(cardItem.data.id, cardItem.data.star + 1, cardItem.data.name));
        node.setParent(this.node_cardRoot);
        node.setPosition(v3(endX, 0, 0));
        tween(node)
            .to(time, { position: this.cardPos[idx] })
            .call(() => this.updateOtherNodePos())
            .start();
        return comp;
    }

    /** 更新其他节点位置 */
    updateOtherNodePos() {
        const time = 0.5;
        let promiseArr: Promise<void>[] = [];
        // 位置动画
        for (let i = 0; i < this.comp_cardItem.length; i++) {
            if (this.comp_cardItem[i].node.getPosition().x != this.cardPos[i].x) {
                let promise = new Promise<void>((resolve, reject) => {
                    tween(this.comp_cardItem[i].node)
                        .to(time, { position: this.cardPos[i] })
                        .call(() => resolve())
                        .start();
                })
                promiseArr.push(promise);
            }
        }
        Promise.all(promiseArr).then(() => {
            log('全部位置修正完成')
            let node = instantiate(this.pre_card);
            let comp = node.getComponent(CardItem);
            comp.setData(CardData.ins.getCard());
            node.setParent(this.node_cardRoot);
            node.setPosition(this.cardPos[CardData.ins.CardArrLength - 1]);
            this.comp_cardItem.push(node.getComponent(CardItem));
            this.judgeAdjacent();
        })
    }

    /** 判断ID和星级是否相同 */
    getIDAndStarSame(card: CardStruct, targetCard: CardStruct) {
        if (card.star == E_CardStar.three || targetCard.star == E_CardStar.three) return false;

        return card.id === targetCard.id && card.star === targetCard.star;
    }

    onClickRefresh() {
        if (this.isPlayingAnima) return;
        this.isPlayingAnima = true;
        this.node_cardRoot.removeAllChildren();
        this.comp_cardItem = [];
        this.initCard();
    }

    ConsoleItemData(info?: string) {
        for (let i = 0; i < this.comp_cardItem.length; i++) {
            log(info, this.comp_cardItem[i]?.data)
        }
    }
}


